<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
    <canvas id="physicsCanvas" width="550" height="480"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 3;
        ctx.lineCap = 'round';
        ctx.font = 'bold 22px sans-serif';

        // Parameters
        const origin = { x: 220, y: 240 };
        const D = 160;
        const plate_len = 250;
        const plate_thickness = 10;
        const plate_y_top = origin.y - D / 2;
        const plate_y_bottom = origin.y + D / 2;
        const plate_x_start = origin.x - 170;
        const plate_x_end = plate_x_start + plate_len;

        // Helper function to draw an arrowhead
        function drawArrowHead(ctx, x, y, angle) {
            const headlen = 12;
            ctx.save();
            ctx.beginPath();
            ctx.translate(x, y);
            ctx.rotate(angle);
            ctx.moveTo(0, 0);
            ctx.lineTo(-headlen, headlen / 2);
            ctx.moveTo(0, 0);
            ctx.lineTo(-headlen, -headlen / 2);
            ctx.stroke();
            ctx.restore();
        }

        // 1. Draw Plates
        ctx.fillRect(plate_x_start, plate_y_top - plate_thickness / 2, plate_len, plate_thickness);
        ctx.fillRect(plate_x_start, plate_y_bottom - plate_thickness / 2, plate_len, plate_thickness);

        // 2. Draw Wire
        ctx.beginPath();
        ctx.moveTo(plate_x_end, plate_y_top);
        ctx.quadraticCurveTo(plate_x_end + 60, origin.y, plate_x_end, plate_y_bottom);
        ctx.stroke();
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('wire', plate_x_end + 50, origin.y - 15);

        // 3. Draw Coordinate Axes
        // x-axis
        ctx.beginPath();
        ctx.moveTo(origin.x, origin.y);
        ctx.lineTo(origin.x + 200, origin.y);
        ctx.stroke();
        drawArrowHead(ctx, origin.x + 200, origin.y, 0);
        // z-axis
        ctx.beginPath();
        ctx.moveTo(origin.x, origin.y);
        ctx.lineTo(origin.x, origin.y + 150);
        ctx.stroke();
        drawArrowHead(ctx, origin.x, origin.y + 150, Math.PI / 2);
        
        // Axis labels
        ctx.textAlign = 'left';
        ctx.textBaseline = 'top';
        ctx.fillText('x', origin.x + 210, origin.y + 5);
        ctx.textAlign = 'center';
        ctx.fillText('z', origin.x + 15, origin.y + 155);


        // 4. Draw Charge Q at Origin O
        // The point itself
        ctx.beginPath();
        ctx.arc(origin.x, origin.y, 3, 0, 2 * Math.PI);
        ctx.fill();
        // Labels Q and ȯ
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('Q', origin.x + 18, origin.y - 18);
        ctx.font = 'bold 20px sans-serif';
        ctx.fillText('o', origin.x - 18, origin.y + 15);
        ctx.beginPath();
        ctx.arc(origin.x - 18, origin.y + 6, 1.5, 0, 2 * Math.PI);
        ctx.fill();
        ctx.font = 'bold 22px sans-serif';


        // 5. Draw Distance D marker
        const d_marker_x = plate_x_start - 40;
        ctx.beginPath();
        ctx.moveTo(d_marker_x, plate_y_top);
        ctx.lineTo(d_marker_x, plate_y_bottom);
        ctx.stroke();
        drawArrowHead(ctx, d_marker_x, plate_y_top, -Math.PI / 2);
        drawArrowHead(ctx, d_marker_x, plate_y_bottom, Math.PI / 2);
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('D', d_marker_x, origin.y);


        // 6. Draw Point A and Triangle
        const a_x_coord = 100;
        const pA_x = origin.x + a_x_coord;
        const pA_y = plate_y_bottom;
        // Solid line from O to A
        ctx.beginPath();
        ctx.moveTo(origin.x, origin.y);
        ctx.lineTo(pA_x, pA_y);
        ctx.stroke();
        // Dashed line
        ctx.save();
        ctx.beginPath();
        ctx.setLineDash([6, 5]);
        ctx.moveTo(pA_x, origin.y);
        ctx.lineTo(pA_x, pA_y);
        ctx.stroke();
        ctx.restore();
        // Filled arrow at A
        const a_y_surface = plate_y_bottom - plate_thickness / 2;
        const arrow_height_A = 12;
        ctx.beginPath();
        ctx.moveTo(pA_x, a_y_surface);
        ctx.lineTo(pA_x - 6, a_y_surface + arrow_height_A);
        ctx.lineTo(pA_x + 6, a_y_surface + arrow_height_A);
        ctx.closePath();
        ctx.fill();
        // Label A
        ctx.textAlign = 'center';
        ctx.textBaseline = 'top';
        ctx.fillText('A', pA_x, pA_y + plate_thickness/2 + 8);


        // 7. Draw Figure Caption
        ctx.font = '20px sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('Fig. 1.40', canvas.width / 2, canvas.height - 20);

    </script>
</body>
</html>